using System;
using Microsoft.SPOT;
using System.Threading;
using System.Net;
using System.Net.Sockets;
using SDCard;

namespace WebServer
{
    public class NetduinoTime
    {
        public static DateTime UninitialisedTime = new DateTime(1900, 1, 1);
        private static DateTime _BootTime = UninitialisedTime;

        public NetduinoTime()
        {
        }

        public static DateTime BootTime
        {
            get { return _BootTime; }
        }

        public static DateTime NTPTime(String TimeServer, int UTC_offset)
        {
            Thread.Sleep(500); // todo give other processes a chance if ntp or dns not working
            // Find endpoint for timeserver
            IPEndPoint ep = new IPEndPoint(Dns.GetHostEntry(TimeServer).AddressList[0], 123);

            // Connect to timeserver
            Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            //s.Connect(ep);

            // Make send/receive buffer
            byte[] ntpData = new byte[48];
            Array.Clear(ntpData, 0, 48);

            // Set protocol version
            ntpData[0] = 0x1B;

            // Send Request
            // s.Send(ntpData);
            s.SendTo(ntpData, ep);

            s.ReceiveTimeout = 1000;
            // Receive Time
            DateTime networkDateTime = UninitialisedTime;
            try
            {
                s.Receive(ntpData);
                byte offsetTransmitTime = 40;
                ulong intpart = 0;
                ulong fractpart = 0;
                for (int i = 0; i <= 3; i++)
                {
                    intpart = (intpart << 8) | ntpData[offsetTransmitTime + i];
                }
                for (int i = 4; i <= 7; i++)
                {
                    fractpart = (fractpart << 8) | ntpData[offsetTransmitTime + i];
                }
                ulong milliseconds = (intpart * 1000 + (fractpart * 1000) / 0x100000000L);
                TimeSpan timeSpan = TimeSpan.FromTicks((long)milliseconds * TimeSpan.TicksPerMillisecond);
                DateTime dateTime = UninitialisedTime;
                dateTime += timeSpan;

                TimeSpan offsetAmount = new TimeSpan(0, UTC_offset, 0, 0, 0);
                networkDateTime = (dateTime + offsetAmount);
                if (_BootTime == UninitialisedTime)
                {
                    _BootTime = networkDateTime;// only set once
                }

            }
            catch (SocketException ex)
            {
                ConsoleWrite.Print("Error getting ntp time: " + ex.Message);
            }
            finally
            {
                s.Close();
            }
            return networkDateTime;
        }
    }
}
